package org.chs.ts.base.common.util;

import org.owasp.esapi.ESAPI;
import org.owasp.esapi.Encoder;
import org.owasp.esapi.errors.EncodingException;

import java.lang.reflect.Field;
import java.net.URLDecoder;
import java.util.List;
import java.util.Map;

/**
 * @author wuwei
 * @date 2024/11/22
 * @apiNote
 */
public class XssFilterUtils {

    public static List<String> filterXss(List<String> list) {
        for (String s : list) {
            s = XssFilterUtils.filterXss(s);
        }
        return list;
    }

    public static String filterXssHtml(String input){
        if (input ==null) {
            return null;
        }

        String xssStr = "";

        try {
            Encoder encoder = ESAPI.encoder();
            xssStr = encoder.encodeForURL(input);
        } catch (Exception e) {
            e.printStackTrace();
        }

        if (!xssStr.equals(input)) {
            throw new RuntimeException("检测到xss危险。源数据："+input+"。过滤后："+input);
        }

        return xssStr;
    }

    public static String filterXss(String input){
        if (input == null) {
            return null;
        }

        String xssStr = "";

        try {
            Encoder encoder = ESAPI.encoder();
            xssStr = URLDecoder.decode(encoder.encodeForURL(input));
        } catch (Exception e) {
            e.printStackTrace();
        }

        if (!xssStr.equals(input)) {
            throw new RuntimeException("检测到xss危险。源数据："+input+"。过滤后："+input);
        }
        return xssStr;
    }

    public static Map<String,Object> filterXss(Map<String,Object> inputMap){
        if (inputMap ==null) {
            return null;
        }

        Encoder encoder = ESAPI.encoder();

        for (Map.Entry<String, Object> entry : inputMap.entrySet()) {
            Object value = entry.getValue();
            if (value instanceof String) {
                String filteredValue = encoder.encodeForCSS((String) value);
                entry.setValue(filteredValue);
            }
        }

        return inputMap;
    }

    public static<T> T filterXss(T object){
        if (object ==null) {
            return null;
        }

        Encoder encoder = ESAPI.encoder();
        Class clazz = object.getClass();

        if (object !=null) {
            for (Field field : clazz.getDeclaredFields()) {
                if (field.getType()==String.class) {
                    field.setAccessible(true);

                    try {
                        String value = (String)field.get(object);
                        if (value!=null) {
                            String xssStr = URLDecoder.decode(encoder.encodeForURL(value));
                            if (!xssStr.equals(value)) {
                                throw new RuntimeException("检测到xss危险。源数据："+value+"。过滤后："+xssStr);
                            }
                            field.set(object,xssStr);
                        }
                    } catch (IllegalAccessException e) {
                        throw new RuntimeException(e);
                    } catch (EncodingException e) {
                        throw new RuntimeException(e);
                    }
                }
            }
        }

        return object;
    }
}
